Ext.namespace("Milan.widget.tree");

/**
 * Copyright (C), 2004-2006, 三五互联科技有限公司
 * File Name: 
 * Encoding UTF-8
 * @author 万毅 (wanyi@china-channel.com)
 * 
 * 对原PosTree做了重构，使得各个树都拥有自己的一组全局变量
 * 
 * Date: 2008-4-22
 * Version: 1.0
 */

Milan.widget.tree.Tree = Class.create();

Milan.widget.tree.Tree.prototype = {

    initialize: function(id, data){
        this.id = id||"milan_Tree_id";
        this.nodes = new Array();
        this.add = this.addNode;
        this.write = this.writeTree;
        this.seek = this.seekNode;
        this.seekByName = this.seekNodesByName;
        this.unshow = this.unshowtree;
        this.activenode = this.getactivenode;
        this.query = this.treequery;
        this.autochecksubnode = false;
        this.autoInvokeSubCheckNodeEvent = true;
        this.autoexpand = false;
        this.clicktocheck = true;
        this.treelist = new Array();
        this.check = this.treecheck;
        this.enableclick = true;
        this.activeTxtObj = null;
        this.queryNodes = new Array();
        this.displayObjs = new Array();
        this.checkboxs = new Array();
    },
    
    addNode: function(node){
        node.parent = null;
        this.nodes[this.nodes.length] = node;
        node.tree = this;
    },
    writeTree: function(){
        var treeString = '';
        var numNodes = this.nodes.length;
        for (var i = 0; i < numNodes; i++) 
            treeString += this.nodes[i].write();
        return treeString;
    },
    seekNode: function(nodeID){
        var tmpNode = new Milan.widget.tree.Node();
        var numNodes = this.nodes.length;
        
        for (var i = 0; i < numNodes; i++) {
            if (this.nodes[i].id == nodeID) 
                return this.nodes[i];
            tmpNode = this.nodes[i].seek(nodeID);
            if (tmpNode != null) 
                return tmpNode;
        }
    },
    seekNodesByName: function(nodeName){
        var subNodes = new Array();
        var rNodes = new Array();
        var numNodes = this.nodes.length;
        nodeName = nodeName.toUpperCase();
        for (var i = 0; i < numNodes; i++) {
            if (this.nodes[i].text.toUpperCase().indexOf(nodeName) > -1) {
                rNodes[rNodes.length] = this.nodes[i];
            }
            subNodes = this.nodes[i].seekByName(nodeName);
            if (subNodes.length > 0) {
                rNodes = rNodes.concat(subNodes);
            }
        }
        return rNodes;
    },
    unshowtree: function(){
    	var ilen=this.nodes.length;
        for (i = 0; i < ilen; i++) {
            this.nodes[i].unshow();
        }
    },
    getactivenode: function(){
        if (this.activeTxtObj == null) 
            return null;
        return this.seek(this.activeTxtObj.id);
    },
    treequery: function(strCon){
        for (var i = 0,ilen=queryNodes.length; i < ilen; i++) {
            queryNodes[i].undisplay();
        }
        
        queryNodes = this.seekByName(strCon);
        if (queryNodes.length > 0) {
            for (var i = 0,ilen=queryNodes.length; i < ilen; i++) {
                queryNodes[i].display();
            }
            return queryNodes;
        }
        else {
            return null;
        }
    },
    treecheck: function(checkvalue){
        var tmpenableclick = this.enableclick;
        var tmpautochecksubnode = this.autochecksubnode;
        
        this.enableclick = false;
        this.autochecksubnode = true;
        try {
            for (var i = 0,ilen=this.nodes.length; i <ilen; i++) {
                this.nodes[i].check(checkvalue);
            }
        } 
        catch (exception) {
        }
        this.enableclick = tmpenableclick;
        this.autochecksubnode = tmpautochecksubnode;
    },
    startListener: function(){
        for (var i = 0,ilen=this.nodes.length; i < ilen; i++) {
            this.nodes[i].listenStart();
        }
    }
}


Milan.widget.tree.Node = Class.create();

Milan.widget.tree.Node.prototype = {


    initialize: function(id, text, link, imageObjConfig, nodeEventConfig){
        this.id = id || "milan_tree_node_id";
        this.text = text;
        this.link = link;
        this.openImg = new Image;
        this.closedImg = new Image;
        this.nodeImg = new Image;
        if (imageObjConfig) {
            this.openImg.src = imageObjConfig.openImgSrc || Milan.skinType + "images/open.gif";
            this.closedImg.src = imageObjConfig.closeImgSrc || Milan.skinType + "images/closed.gif";
            this.nodeImg.src = imageObjConfig.nodeImgSrc || Milan.skinType + "images/doc.gif";
        }
        else {
            this.openImg.src = Milan.skinType + "images/open.gif";
            this.closedImg.src = Milan.skinType + "images/closed.gif";
            this.nodeImg.src = Milan.skinType + "images/doc.gif";
        }
        if (nodeEventConfig) {
            this.NodeChkClick = nodeEventConfig.NodeChkClick ||
            function(){
				//alert("There is no NodeChkClick Listener");
            };
            this.NodeButtonClick = nodeEventConfig.NodeButtonClick ||
            function(){
				//alert("There is no NodeButtonClick Listener");
            };
            this.NodeDblClick = nodeEventConfig.NodeDblClick ||
            function(){
				//alert("There is no NodeDblClick Listener");
            };
			this.NodeClick = nodeEventConfig.NodeClick ||
			function(){
				//alert("There is no NodeClick Listener");
			};
        }
        else {
            this.NodeChkClick = function(){
            };
            this.NodeButtonClick = function(){
            };
            this.NodeDblClick = function(){
            };
        }
        
        this.write = this.writeNode;
        this.add = this.addSubNode;
        this.title = "";
        this.nodes = new Array();
        this.parent = null;
        this.seek = this.seekNode;                //根据节点id查询节点,注意此节点仅仅就是new Node的时候指定的那个nodeId
        this.show = this.showself;
        this.unshow = this.unshowself;
        this.hreftarget = '';
        this.isopen = false;
        this.dataarray = new Array();             //该节点的一些附加信息，比如岗位编号，岗位名称
        this.nodebutton = '';
        this.seekByName = this.seekNodesByName;   //根据节点名称查询节点，注意此节点名称仅仅就是指new Node的时候指定的nodeName
        this.display = this.displayNode;
        this.undisplay = this.undisplayNode;
        this.addCheckbox = false;
        this.check = this.nodecheck;              //选中改节点，如果tree的autochecksubnode属性打开了，则会自动选择所有子节点。如果tree开启了
											      //enableclick属性，还会自动触发子结点的NodeChkClick方法
        this.tree = null;
    },
    writeNode: function(){
        var ReturnString = '';
        var ImagePath = '';
        var NodeButton = '';
        var strTitle = '';
        var strAddCheck = '';
        
		var treeId = this.tree.id;
		
        if (this.closedImg && this.closedImg.src.length == 0) 
            ImagePath = this.nodeImg.src;
        else 
            ImagePath = this.closedimg;
        
        if (this.title.length > 0) 
            strTitle = 'title="' + this.title + '"';
        
        if (this.addCheckbox) {
            strAddCheck = '<input id="'+treeId+'chk' + this.id + '" type="checkbox" name="chkSelect" value="' + this.id + '" title="' + this.text + '">';
        }
        if (this.nodebutton != '') {
            NodeButton = '&nbsp&nbsp<span id="'+treeId + this.id + '" class="txtClassNormal"  name="tree_nodeButtonName">' + this.nodebutton + '</span>';
        }
        if (this.nodes.length == 0) {
            ReturnString += '<span class="mainspan"><span class="imagespan"><img ' + strTitle + ' name="tree_FolderImageName" align="absmiddle" src="' + ImagePath + '" id="'+treeId+'Img' + this.id + '"></span>&nbsp;' + strAddCheck + '<span name="tree_txtSpanAddCheckName" id="'+treeId + this.id + '" class="txtClassNormal" >' + this.text + '</span>' + NodeButton + '</span>';
        }
        else {
            ReturnString += '<span class="mainspan"><span id="'+treeId+'span_' + this.id + '" class="imagespan" name="tree_spanshowNodeName" ><img ' + strTitle + ' align="absmiddle" src="' + ImagePath + '" id="'+treeId+'Img' + this.id + '"></span>&nbsp;' + strAddCheck + '<span name="tree_txtSpanNodeButtonName" id="'+treeId + this.id + '" class="txtClassNormal">' + this.text + '</span>' + NodeButton + '</span>';
        }
        ReturnString += '<span class="childspan" id="'+treeId+'child' + this.id + '">';
        var numNodes = this.nodes.length;
        for (var j = 0; j < numNodes; j++) 
            ReturnString += this.nodes[j].write();
        ReturnString += '</span>';
        return ReturnString;
    },
    listenStart: function(){
		var treeId = this.tree.id;
		var nodeslen=this.nodes.length;
		if (nodeslen > 0) {
			for (var i = 0; i < nodeslen; i++) {
				this.nodes[i].listenStart(this.nodes[i]);
			}
		}
        var obj1 = document.getElementById(treeId+"chk" + this.id);
        if (obj1) 
            obj1.onclick = function(id){
                this.chkClick(id);
            }.bind(this, this.id);
        
        var obj2 = document.getElementById(treeId+this.id);
        if (obj2) {
            if (obj2.getAttribute("name") == "tree_nodeButtonName") {
                obj2.onclick = function(ele){
                    this.ClickNodeButton(ele);
                }.bind(this, obj2);
                obj2.onmouseout = function(ele){
                    this.doMouseOut(ele)
                }.bind(this, obj2);
                obj2.onmouseover = function(ele){
                    this.doMouseOver(ele);
                }.bind(this, obj2);
            }
            if (obj2.getAttribute("name") == "tree_txtSpanAddCheckName" || obj2.getAttribute("name") == "tree_txtSpanNodeButtonName") {
                obj2.onclick = function(ele){
                    this.ClickText(ele);
                }.bind(this, obj2);
                obj2.ondblclick = function(ele){
                    this.DblClickText(ele);
                }.bind(this, obj2);
                obj2.onmouseout = function(ele){
                    this.doMouseOut(ele);
                }.bind(this, obj2);
                obj2.onmouseover = function(ele){
                    this.doMouseOver(ele);
                }.bind(this, obj2);
            }
        }
        var obj3 = document.getElementById(treeId+"Img" + this.id);
        if (obj3 && obj3.name == "tree_FolderImageName") 
            obj3.onclick = function(id){
                this.ClickTextByID(id);
            }.bind(this, this.id);
        
        var obj4 = document.getElementById(treeId+"span_" + this.id);
		if(obj4)
	        obj4.onclick = function(id){
	            this.showNode('child' + id);
	        }.bind(this, this.id);
    },
    addSubNode: function(node){
        node.parent = this;
        this.nodes[this.nodes.length] = node;
        node.tree = this.tree;
    },
    seekNode: function(nodeID){
        var tmpNode = new Milan.widget.tree.Node();
        var numNodes = this.nodes.length;
        
        for (var i = 0; i < numNodes; i++) {
            if (this.nodes[i].id == nodeID) 
                return this.nodes[i];
            tmpNode = this.nodes[i].seek(nodeID);
            if (tmpNode != null) 
                return tmpNode;
        }
    },
    showself: function(){
		var treeId = this.tree.id;
        this.showit('child' + this.id);
        
        if (this.parent == null) {
            var nodeobj = document.getElementById(treeId+this.id);
            this.ClickTextStyle(nodeobj);
            return 0;
        }
        
        var pNode = this.parent;
        do {
            this.showit('child' + pNode.id);
            pNode = pNode.parent;
        }
        while (pNode != null)
        
        var nodeobj = document.getElementById(treeId+this.id);
        this.ClickTextStyle(nodeobj);
    },
    showit: function(childnodeID){
		var treeId = this.tree.id;
        var objBranch = document.getElementById(treeId+childnodeID).style;
        objBranch.display = "block";
        var nodeID = childnodeID.substring(childnodeID.indexOf("child") + 5);
        
        this.swap2OpenFolder(nodeID);
    },
    ClickTextStyle: function(TxtObj){
        if (this.tree.activeTxtObj != null) {
            this.tree.activeTxtObj.className = 'txtClassNoraml';
        }
        
        for (var i = 0,ilen=this.tree.displayObjs.length; i < ilen; i++) 
            this.tree.displayObjs[i].className = 'txtClassNormal';
        this.tree.displayObjs = new Array();
        
        TxtObj.className = 'txtClassClick';
        this.tree.activeTxtObj = TxtObj;
    },
    swap2OpenFolder: function(nodeID){
		var treeId = this.tree.id;
        nodeImgID = 'Img' + nodeID;
        objImg = document.getElementById(treeId+nodeImgID);
        if (objImg == null) {
            return 0;
        }
        
        var nodeobj = this.tree.seek(nodeID);
        
        if (nodeobj.openimg != '') 
            objImg.src = nodeobj.openimg;
        else 
            objImg.src = openImg.src;
        nodeobj.isopen = true;
    },
    unshowself: function(){
        this.unshowit('child' + this.id);
        if (this.parent == null) 
            return 0;
        this.parent.unshow();
    },
    unshowit: function(childnodeID){
		var treeId = this.tree.id;
        var objBranch = document.getElementById(treeId+childnodeID).style;
        objBranch.display = "none";
        var nodeID = childnodeID.substring(childnodeID.indexOf("child") + 5);
        
        this.swap2CloseFolder(nodeID);
    },
    swap2CloseFolder: function(nodeID){
		var treeId = this.tree.id;
        nodeImgID = 'Img' + nodeID;
        objImg = document.getElementById(treeId+nodeImgID);
        if (objImg == null) {
            return 0;
        }
        
        var nodeobj = this.tree.seek(nodeID);
        
        if (nodeobj.closedimg != '') 
            objImg.src = nodeobj.closedimg;
        else 
            objImg.src = closedImg.src;
        nodeobj.isopen = false;
    },
    seekNodesByName: function(nodeName){
        var subNodes = new Array();
        var rNodes = new Array();
        var numNodes = this.nodes.length;
        nodeName = nodeName.toUpperCase();
        for (var i = 0; i < numNodes; i++) {
            if (this.nodes[i].text.toUpperCase().indexOf(nodeName) > -1) {
                rNodes[rNodes.length] = this.nodes[i];
            }
            subNodes = this.nodes[i].seekByName(nodeName);
            if (subNodes.length > 0) {
                rNodes = rNodes.concat(subNodes);
            }
        }
        return rNodes;
    },
    displayNode: function(){
		var treeId = this.tree.id;
        this.showit('child' + this.id);
        if (this.parent == null) {
            var nodeobj = document.getElementById(treeId+this.id);
            this.DisplayTextStyle(nodeobj);
            return 0;
        }
        
        var pNode = this.parent;
        do {
            showit('child' + pNode.id);
            pNode = pNode.parent;
        }
        while (pNode != null)
        
        var nodeobj = document.getElementById(treeId+this.id);
        this.DisplayTextStyle(nodeobj);
    },
    DisplayTextStyle: function(TxtObj){
        TxtObj.className = 'txtClassDisplay';
        this.tree.displayObjs[this.tree.displayObjs.length] = TxtObj;
    },
    undisplayNode: function(){
		var treeId = this.tree.id;
        var nodeobj = document.getElementById(treeId+this.id);
        this.unDisplayTextStyle(nodeobj);
    },
    unDisplayTextStyle: function(TxtObj){
        TxtObj.className = 'txtClassNormal';
    },
    nodecheck: function(checkvalue,invokeChildEvent){
		var treeId = this.tree.id;
        var numNodes = this.nodes.length;
        var ChkObj,tempChkObj;
        ChkObj = document.getElementById(treeId+"chk" + this.id);

        if (ChkObj != null) {
            ChkObj.checked = checkvalue;
            if (ChkObj.checked) {
                this.AddCheckedObj(this);
            }
            else {
                this.RemoveCheckedObj(this);
            }
        }
        
        if (this.tree.autochecksubnode) {
            for (var i = 0; i < numNodes; i++) {
                tempChkObj = document.getElementById(treeId+"chk" + this.nodes[i].id);
                if (tempChkObj != null) {
                    tempChkObj.checked = checkvalue;
                    if (checkvalue) {
                        this.AddCheckedObj(this.nodes[i]);
                    }
                    else {
                        this.RemoveCheckedObj(this.nodes[i]);
                    }
                 }
                this.nodes[i].check(checkvalue,this.tree.autoInvokeSubCheckNodeEvent);
            }
        }
        try {
            if (this.tree.enableclick&&(invokeChildEvent==undefined||invokeChildEvent))
            {
				this.NodeChkClick(ChkObj);
			}
        } 
        catch (exception) {
            alert("有错误发生!" + exception);
        }
    },
    AddCheckedObj: function(obj){
        var tmpLength = this.tree.checkboxs.length;
        for (var i = 0; i < tmpLength; i++) {
            if (this.tree.checkboxs[i] != null && this.tree.checkboxs[i] == obj) {
                return;
            }
        }
        
        for (var i = 0; i < tmpLength; i++) {
            if (this.tree.checkboxs[i] == null) {
                this.tree.checkboxs[i] = obj;
                return;
            }
        }
        this.tree.checkboxs[this.tree.checkboxs.length] = obj;
    },
    RemoveCheckedObj: function(obj){
        var tmpLength = this.tree.checkboxs.length;
        for (var i = 0; i < tmpLength; i++) {
            if (this.tree.checkboxs[i] == obj) {
                this.tree.checkboxs[i] = null;
                return;
            }
        }
    },
    
    showNode: function(childnodeID){
		var treeId = this.tree.id;
        var objBranch = document.getElementById(treeId+childnodeID).style;
        if (objBranch.display == "block") {
            objBranch.display = "none";
        }
        else {
            objBranch.display = "block";
        }
        var nodeID = childnodeID.substring(childnodeID.indexOf("child") + 5);
        this.swapFolder(nodeID);
    },
    swapFolder: function(nodeID){
		var treeId = this.tree.id;
        nodeImgID = 'Img' + nodeID;
        objImg = document.getElementById(treeId+nodeImgID);
        if (objImg == null) {
            return 0;
        }
        
        var nodeobj = this.tree.seek(nodeID);
        
        
        if (nodeobj.isopen) {
            if (nodeobj.closedimg != '') 
                objImg.src = nodeobj.closedimg;
            else 
                objImg.src = closedImg.src;
        }
        else {
            if (nodeobj.openimg != '') 
                objImg.src = nodeobj.openimg;
            else 
                objImg.src = openImg.src;
        }
        
        
        nodeobj.isopen = !nodeobj.isopen;
    },
    doMouseOver: function(Txtobj){
        if (this.tree.activeTxtObj == Txtobj) {
            return;
        }
        Txtobj.className = 'txtClassMouseOver';
    },
    doMouseOut: function(Txtobj){
        if (this.tree.activeTxtObj == Txtobj) 
            return;
        for (var i = 0,ilen=this.tree.displayObjs.length; i < ilen; i++) {
            if (this.tree.displayObjs[i] == Txtobj) {
                Txtobj.className = 'txtClassDisplay';
                return;
            }
        }
        
        Txtobj.className = 'txtClassNoraml';
    },
    ClickNodeButton: function(TxtObj){
        if (this.tree.activeTxtObj != null) {
            this.tree.activeTxtObj.className = 'txtClassNoraml';
        }
        TxtObj.className = 'txtClassClick';
        this.tree.activeTxtObj = TxtObj;
        try {
            if (this.tree.enableclick) 
                this.NodeButtonClick(TxtObj);
        } 
        catch (exception) {
            alert("有错误发生!" + exception);
        }
    },
    chkClick: function(NodeID){
		var treeId = this.tree.id;
        var ChkObj = document.getElementById(treeId+"chk" + NodeID);
        if (ChkObj == null) {
            alert("选择错误,请重新选择!");
            return;
        }

        if (!this.tree.enableclick) {
            ChkObj.checked = !ChkObj.checked;
            return;
        }

        for (var i = 0,ilen=this.tree.displayObjs.length; i < ilen; i++) 
            this.tree.displayObjs[i].className = 'txtClassNormal';
        this.tree.displayObjs = new Array();

        var tmpNode = this.tree.seek(NodeID);
        if (tmpNode != null) 
            tmpNode.check(ChkObj.checked);
    },
    ClickTextByID: function(TxtObjID){
		var treeId = this.tree.id;
        var TxtObj = document.getElementById(treeId+TxtObjID);
        if (TxtObj != null) 
            this.ClickText(TxtObj);
    },
    ClickText: function(TxtObj){
		var treeId = this.tree.id;
        this.ClickTextStyle(TxtObj);
        if (this.tree.autoexpand) 
            this.showNode('child' + this.id);
        
        if (this.tree.enableclick && this.tree.clicktocheck) {
            var chk = document.getElementById(treeId+"chk" + TxtObj.id);
            if (chk != null) {
                var tmpNode = this.tree.seek(TxtObj.id);
                if (tmpNode != null) 
                    tmpNode.check(!chk.checked);
            }
        }

        try {
            if (this.tree.enableclick) 
                this.NodeClick(TxtObj);
        } 
        catch (exception) {
            alert("有错误发生!" + exception);
        }
    },
    DblClickText: function(){
        try {
            if (this.tree.enableclick) 
                this.NodeDblClick(TxtObj);
        } 
        catch (exception) {
        
        }
    },
    isAllChildChecked : function(){
    	var children = this.nodes;
    	var treeId = this.tree.id;
    	var child,childChk;
    	for(var i=0,ilen=children.length;i<ilen;i++)
    	{
    		child = children[i];
    		childChk = document.getElementById(treeId+"chk"+child.id);
    		if(!childChk.checked)
    			return false;
    	}
    	return true;
    },
    NodeChkClick: function(ChkObj){
        //alert("NodeChkClick");
    },
    NodeButtonClick: function(TxtObj){
        //alert("NodeButtonClick: " + TxtObj);
    },
    NodeDblClick: function(TxtObj){
        //alert("NodeDblClick: " + TxtObj);
    },
	NodeClick : function(TxtObj)
	{
		//alert("NodeClick: " + TxtObj);
	}
}
